#include "download.srpc.h"
#include <workflow/MySQLResult.h>
#include <wfrest/HttpServer.h>
#include <workflow/WFFacilities.h>
#include <map>
#include <iostream>
#include <signal.h>
#include <string>

#include <chrono>
#include "ppconsul/agent.h"

using namespace ppconsul::agent;
using ppconsul::Consul;
using std::string;
using std::map;

using namespace wfrest;
using namespace srpc;
using namespace protocol;




static WFFacilities::WaitGroup wait_group(1);

void sig_handler(int )
{
	wait_group.done();
}

class DownLoadServiceImpl : public DownLoad::Service
{
public:

	void downLoad(DownLoadRequest *request, DownLoadResponse *response, srpc::RPCContext *ctx) override
	{
		SeriesWork * series = ctx->get_series();
		string filePath = request->filepath();

		int fd = ::open(filePath.c_str(),O_RDONLY);
            size_t size = lseek(fd, 0, SEEK_END);
            char * buf = (char *)malloc(size);        
            WFFileIOTask *pread_task;

            pread_task = WFTaskFactory::create_pread_task(fd, buf, size, 0, &DownLoadServiceImpl::pread_callback);
           
            pread_task->user_data = response;  

            series->set_callback([buf](const SeriesWork *){  free(buf); });
            
            series->push_back(pread_task);
	}
private:
static void pread_callback(WFFileIOTask *task){
    FileIOArgs *args = task->get_args();
    long ret = task->get_retval();
    DownLoadResponse *resp = (DownLoadResponse *)task->user_data;

    close(args->fd);
    if (ret < 0)
    {
		resp->set_success(0);
        resp->set_code(503);
        resp->set_content("<html>503 Internal Server Error.</html>");
    }
    else{
		resp->set_success(1);
        resp->set_content(string((char *)args->buf));
    }
}
};


static void timer_callback(WFTimerTask* task)
{
    Agent* agent = (Agent*)task->user_data;
    agent->servicePass("downLoadService1");

    WFTimerTask* next = WFTaskFactory::create_timer_task(7, 0, timer_callback);
    next->user_data = task->user_data;

    series_of(task)->push_back(next);
}

int main()
{
    signal(SIGINT,sig_handler); 
    GOOGLE_PROTOBUF_VERIFY_VERSION;
    unsigned short port = 1416;
    SRPCServer server;

    DownLoadServiceImpl downLoad_impl;
    server.add_service(&downLoad_impl);

    if(server.start(port) == 0){

        Consul consul { "http://127.0.0.1:8500", ppconsul::kw::dc="dc1" };
        Agent agent { consul };
        // 注册服务 
        agent.registerService(
        kw::id = "downLoadService1",
        kw::name = "downLoadService",
        kw::address = "127.0.0.1",
        kw::port = 1416,
        kw::check = TtlCheck(std::chrono::seconds{ 10 })
        );

        WFTimerTask* timerTask = WFTaskFactory::create_timer_task("timer",7, 0, timer_callback);
        timerTask->user_data = &agent;
        timerTask->start();


        wait_group.wait();
        server.stop();
        google::protobuf::ShutdownProtobufLibrary();
    }else{
        std::cerr << "Error: start signserver failed!\n";
        std::exit(1);
    }

    return 0;
}
